

// 表单内部需要的 state
import { reactive } from 'vue'
import { defineStore, useStoreLocal } from '@naturefw/nf-state'

import type {
  IAnyObject,
  IFromProps, // 表单控件需要的 meta
  FormColSpan,
  ShowCol,
  IFormState
} from '../../main'

const key = Symbol('nf-form-state')

/**
 * 状态说明：
 * * 来自 配置信息的数据
 * * * formMeta
 * * * * columnsNumber: number = 2
 * * * * colOrder: Array<number> 字段ID，排序依据
 * * * * linkageMeta: 联动筛选
 * * * * ruleMeta: 验证规则
 * * * * subMeta: 分栏信息
 * * * * customerControl: 扩展组件
 * * * * 字段的控件
 * * * * * meta: colName、controlType 等
 * * * * * props: UI库的组件需要的属性
 * 
 * * 创建的数据
 * * * formColSpan: 多列用的
 * * * showCol: 联动筛选用的
 * * * childMetaList: 字段纯 meta 的集合
 * * * childPropsList: 字段纯 props 的集合
 * * 表单的 props
 * * * model
 * * * partModel 也是依据 联动筛选创建的
 */
export function regFormState<T extends IAnyObject>(props: IFromProps<T>) {

  const state = defineStore<IFormState<T>>(key, () => {
 
    const { 
      formMeta,
      model,
      partModel
    } = props

    // 多列用的
    const formColSpan = reactive<FormColSpan>({})
    // 设置字段的是否可见
    const showCol = reactive<ShowCol>({})

    // 字段的纯 meta
    const childMetaList = {} as IAnyObject
    // 字段的纯 props
    const childPropsList = {} as IAnyObject
    // 转换一下
    Object.keys(props.childPropsList).forEach((key) => {
      childMetaList[key] = props.childPropsList[key].meta
      childPropsList[key] = props.childPropsList[key].props
    })

    const columnsNumber = () => {
      return formMeta.columnsNumber
    }

    return {
      // 表单的 model
      model,
      partModel,
      // 配置
      columnsNumber,
      formMeta: formMeta, // 表单的meta
      ruleMeta: formMeta.ruleMeta, // 验证规则
      colOrder: formMeta.colOrder, // 字段排序
      linkageMeta: formMeta.linkageMeta, // 联动筛选
      // 创建
      childPropsList, // input 的 props
      childMetaList, // 字段的纯 meta
      formColSpan, // 多列用的
      showCol   // 设置字段的是否可见
    }
  })

  return state
}

/**
 * 获取状态
 * @returns 
 */
export function getFormState<T>() {
  const re = useStoreLocal<IFormState<T>>(key)
  return re
}